package pATT.profilingAlgorithm.PersonalSearcher;


import java.io.IOException;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.StringTokenizer;

import pATT.logger.Message;



public class StringTools extends Object {

	private static FileHashTable symbols 		= new FileHashTable(577);

	static{
		try{
			String file = Message.PATH_PERSONALSEARCHER_DATA;
//			symbols.load(Settings.getDataPath()+"symbols.dat", "\\");
			symbols.load(file+"symbols.dat", "\\");
		}catch(IOException ex){System.out.println(ex.toString());}
	}

	private StringTools() {}

  	/**
   	* Returns true if the lookFor string occurs in the base string.
   	*/
  	public static boolean contains(String base, String lookFor){
		boolean result = false;
		int index = base.indexOf(lookFor);
		if(index != -1)
      		result = true;
		return result;
	}

	/**
	* Returns true if the given string contains at least one letter.
	*/
	public static boolean containsLetter(String look){
		boolean result = false;

    	for(int i = 0; i < look.length(); i++){
			if(Character.isLetter(look.charAt(i))){
				result = true;
				i = look.length();
			}
		}
		return result;
	}

	/**
   	* Returns the number of words in a string, using
   	* <code>IOTools.GENERIC_WORD_DELIMITERS</code> as dividing points
   	* between the words.
   	*/
  	public static long countWords(String item){
		long result = 0;
    	StringTokenizer itemIt = new StringTokenizer(item, IOTools.GENERIC_WORD_DELIMITERS);

		while(itemIt.hasMoreTokens()){
			itemIt.nextToken();
			result++;
      	}

		return result;
  	}
  
	/**
	* Returns <code>base</code> without <code>remove</code> (only
   	* the first occurance is removed). If <code>remove</code> doesn't
   	* appear in <code>base</code>, it is returned unchanged.
   	*/
  	public static String removeFirst(String base, String remove){
    	String result;

    	int index = base.indexOf(remove);
    	if(index != -1){
			result = base.substring(0,index) +
	  		base.substring(index+remove.length());
      	}
    	else
      		result = base;
    
		return result;
	}

  /////////////////////////////////////////////////////////////////
  /**
   * Removes duplicate words from the string and also trims
   * whitespace at the beginning and ending of words. The string
   * <code>s</code> is assumed to be a list of terms seperated
   * by commas.
   */
  	public static String removeDuplicates(String s){

		String result = "";
		String temp;
	
		StringTokenizer st = new StringTokenizer(s, ",");
	
		// get the first word and remove surrounding whitspace
		if (st.hasMoreTokens())
		  result = st.nextToken().trim();
	
		// for all remaining words, remove surrounding whitespace, and if
		// the word is already in the string, throw it away
		while(st.hasMoreTokens())
		  {
		temp = st.nextToken().trim();
		if (result.indexOf(temp) == -1) // if item not found
		  result += "," + temp;
		  }
	
		return result;
	}

   	/**
   	* Removes the last character from a string.
   	*/
  	public static String chop(String s){
		String result = s;
		
		if((s != null) && (s.length() > 0))
		  result = s.substring(0, s.length() - 1);
	
		return result;
	}

  	/**
   	* Splits a string into pieces according to the
   	* <code>delimiters</code>, and returns the pieces in an array.
   	*/
  	public static String[] split(String s, String delimiters){
    
		StringTokenizer sTok = new StringTokenizer(s, delimiters);
		String[] result = new String[sTok.countTokens()];
		int i = 0;
		
		while(sTok.hasMoreTokens())
		  {
		result[i] = sTok.nextToken();
		i++;
		  }
	
		return result;
	}
  
  	/**
  	* Creates a HashSet from an array of Strings. Particularly useful for
  	* dealing with the arguments to a <code>main</code> method.
 	*/
 	@SuppressWarnings("unchecked")
	public static HashSet toSet(String[] theArray){
		HashSet theSet = new HashSet();
		for(int i=0; i < theArray.length; i++)
		  theSet.add(theArray[i]);
		return theSet;
	}

	/**
   	* Removes any tags of the form <blah> from the string, and replaces
   	* them with spaces.
   	*/
  public static String removeHtmlTags(String original){
		String result = "";
		int currentIndex = 0;
		int tagStart = original.indexOf("<");
		
		while(tagStart >= 0)
		  {
		result += original.substring(currentIndex, tagStart) + " ";
		int tagEnd = original.indexOf(">", tagStart);
		
		if(tagEnd < 0)
		  {
			break;
		  }
	
		currentIndex = tagEnd + 1;
		tagStart = original.indexOf("<", currentIndex);
		  }
	
		result += original.substring(currentIndex, original.length());
		return result;
	}

	/** Drops all instances of s2 from s1
    *
    * @param s1 Source string
    * @param s2 substring to drop
    */
  	public static String dropAll(String s1, String s2) {
		int location = s1.indexOf(s2);
		String breakDown = s1;
		StringBuffer sb = new StringBuffer();
		while (location>=0) {
		  if (location>0) {
		sb.append(breakDown.substring(0, location));
		  }
		  breakDown = breakDown.substring
		(location+s2.length(), breakDown.length());
		  location=breakDown.indexOf(s2);
		}
		sb.append(breakDown);
		return sb.toString();
	}

	/** Replace all instances of s2 with s3 in s1
    *
    * @param s1 Source string
    * @param s2 String to replace
    * @param s3 What to replace s2 with.
    */
  	public static String replaceAll(String s1, String s2, String s3) {
		int location = s1.indexOf(s2);
		String breakDown = s1;
		StringBuffer sb = new StringBuffer();
		while (location>=0) {
		  if (location>0) {
		sb.append(breakDown.substring(0, location));
		  }
		  sb.append(s3);
		  breakDown = breakDown.substring
		(location+s2.length(), breakDown.length());
		  location=breakDown.indexOf(s2);
		}
		sb.append(breakDown);
		return sb.toString();
	}

	/**
   	* Returns all of the strings occurring in source between beginTag and
   	* endTag.  If a tab opens and never closes, the text until the end of the
   	* file is included.  One use for this class is to get all of the text
   	* occurring between <b>and</b> in an HTML document.  This would give you
   	* all of the boldface text.  NOTE: < b > is not the same as </b> in this
   	* implementation.
   	*
   	*/
  @SuppressWarnings("unchecked")
public static String[] taggedStrings(String source,
				       String beginTag,
				       String endTag,
				       boolean caseSensitive) {
    int level = 0;
    LinkedList ll = new LinkedList();
    TagTokenizer tt = new TagTokenizer(source, new String[] {beginTag, endTag}, true, caseSensitive);
    while (tt.hasMoreTokens()) {
      String token = tt.nextToken();
      if (caseSensitive?token.equals(beginTag):
	  (token.compareToIgnoreCase(beginTag)==0)) level++;
      else if (caseSensitive?token.equals(endTag):
	       (token.compareToIgnoreCase(endTag)==0)) level--;
      else if (level>0) ll.add(token);
    }
    //convert to an array
    String returnStrings[] = new String[ll.size()];
    for (int i = 0; i<returnStrings.length; i++)
      returnStrings[i]=(String)ll.get(i);
    return returnStrings;
  }
    
  ///////////////////////////////////////////////////////////////////////////
  /**
   * Remove all the punctuation, single characters, and white space
   * from the string, using IOTools.GENERIC_WORD_DELIMITERS as the
   * list of things to drop.  Returns a string with all words separated
   * by one space.
   **/
  public static String removeDelimiters(String s) {
    StringBuffer sb = new StringBuffer();
    StringTokenizer st =
      new StringTokenizer(s, IOTools.GENERIC_WORD_DELIMITERS);

    while(st.hasMoreTokens()) {
      String candidate = st.nextToken();
      if (candidate.length()>1)
	sb.append(candidate.toLowerCase()+" ");
    }
    
    return sb.toString();
  }

  ///////////////////////////////////////////////////////////////////////////
  public static String whiteSpaceToSpaces(String s) {
    StringBuffer sb = new StringBuffer();
    StringTokenizer st = new StringTokenizer(s, IOTools.WHITE_SPACE_CHARACTERS);
    while(st.hasMoreTokens()) {
      String candidate = st.nextToken().trim();
      if (candidate.length()>0)
				sb.append(candidate+" ");
    }
    return sb.toString();
  }
    

  ///////////////////////////////////////////////////////////////////////////
  /** Removes all the text occuring between the specified tags.
   * Also removes the tags themselves. Replaces the removed text with a bank
   * space
   *
   */
  public static String removeTaggedStrings(String source,
					   String beginTag,
					   String endTag,
					   boolean caseSensitive) {
    int level = 0;
    StringBuffer sb = new StringBuffer();
    TagTokenizer tt = new TagTokenizer
      (source, new String[] {beginTag, endTag}, true, caseSensitive);
    while (tt.hasMoreTokens()) {
      String token = tt.nextToken();
      if (caseSensitive?token.equals(beginTag):
	  (token.compareToIgnoreCase(beginTag)==0)) level++;
      else if (caseSensitive?token.equals(endTag):
	       (token.compareToIgnoreCase(endTag)==0)) level--;
      else if (level==0) sb.append(token);
      else sb.append(" ");
    }
    return sb.toString();
  }
        
  ///////////////////////////////////////////////////////////////////////////
  /** returns the string with the characters reversed */
  public static String reverse(String st) {
    StringBuffer sb = new StringBuffer();
    char chars[] = st.toCharArray();
    for (int i = chars.length-1; i>=0; i--) {
      sb.append(chars[i]);
    }
    return sb.toString();
  }

  ///////////////////////////////////////////////////////////////////////////
  /**
   * Takes an array of strings and concatenates them together,
   * separated by <code>sep</code>
   *
   * @param array a <code>String[]</code> value
   * @param sep a <code>char</code> value
   * @return a <code>String</code> value
   */
  public static String concat(String[] array, char sep) {
    StringBuffer sb = new StringBuffer();
    for (int i=0;i<array.length; i++) {
      sb.append(array[i]);
      if (i<(array.length-1)) {
	sb.append(sep);
      }
    }
    return sb.toString();
  }

  /////////////////////////////////////////////////////////////////
  /**
     Converts an Object array to a String array.
  **/
  public static String[] makeStringArray(Object[] a)
  {
    String[] result = new String[a.length];
    for(int i = 0; i < a.length; i++)
      {
	result[i] = (String)a[i];
      }

    return result;
  }
  
    public static String replaceAllSymbols(String word) throws StringIndexOutOfBoundsException{
    		String newWord = new String(word);
    		int pos = word.indexOf("&");
				int end = word.indexOf(";");
				if((pos!=-1)&&(end!=-1)&&(pos<end)){
	  				if(word.indexOf("quot")!=-1)
    						newWord = word.substring(0,pos);
    				else{
						    if (end!=-1){
						    		String sbstr = (String)symbols.get(word.substring(pos,end+1));
						    		if (sbstr!=null)
						    				newWord = word.substring(0,pos)+ sbstr;
						    		else
						    				newWord = word.substring(0,pos);
						    		if (end+1<word.length()){
						    				newWord = newWord + replaceAllSymbols(word.substring(end+1,word.length()));
						    		}
						    }
    				}
    				return replaceAllSymbols(newWord);
    		}
				else return newWord;
		}

		public static String cleanTextRef(String pageText){
			pageText = replaceAllSymbols(pageText);
			return whiteSpaceToSpaces(pageText);
		}
}
